package poolConexiones;

import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStream;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.SQLException;
import java.util.Properties;

import logica.excepciones.PersistenciaException;


public class PoolConexiones implements IPoolConexiones {

	private static PoolConexiones instancia; 
	private String driver, url, user, pass; 
	private int nivelTransaccionalidad; 
	private Conexion[] conexiones;
	private int tamanio, creadas, tope;
	 
	public PoolConexiones() throws PersistenciaException, IOException {
		try{
			Properties p = new Properties();
			p.load(new FileInputStream("configuraciones.properties"));
			url = p.getProperty ("url2"); 
			driver = p.getProperty ("driver"); 
			user = p.getProperty ("usuario"); 
			pass = p.getProperty ("pass"); 
			tope=0;
			tamanio = 5; 
			creadas = 0; 
			nivelTransaccionalidad = 1; 
			conexiones = new Conexion [tamanio];
			Class.forName (driver); 
	
		}catch (FileNotFoundException e) {
			throw new PersistenciaException(e.getMessage());
		} catch (ClassNotFoundException e) {
			throw new PersistenciaException(e.getMessage());
		}
		 
	}
	
	 public static synchronized PoolConexiones getInstancia() throws PersistenciaException, IOException  
	 { 
	 	if (instancia == null) 
	 		instancia = new PoolConexiones (); 
		return instancia; 
	 } 
	
	 public synchronized IConexion obtenerConexion (boolean modifica) throws PersistenciaException{ //modifica indica si se va a llevar a cabo una actualizacion o no
	 Connection con = null; 
	 while (con == null){ 
		if (tope > 0) { 
			 con = conexiones [tope-1].getConnection(); 
			 tope--; 
	 	}else
	 		if (creadas < tamanio) 
	 			try{ 
					 con = DriverManager.getConnection (url,user,pass); 
					 con.setTransactionIsolation (nivelTransaccionalidad);
					 con.setAutoCommit (false);
					 creadas++;
				} catch (SQLException e){ 
					throw new PersistenciaException(e.getMessage());
				}
	 		else
	 			try{ 
					wait (); 
				} catch (InterruptedException e){
					throw new PersistenciaException(e.getMessage());
				} 
	} 
	 
	Conexion cone = new Conexion(con);
	return cone; 
	} 


	public synchronized void liberarConexion (IConexion icon, boolean ok) throws PersistenciaException{ //ok indica si la transaccion fue exitosa o no
		Conexion cone = new Conexion(icon.getConnection());
		try{ 
			if (ok) {
				icon.getConnection().commit (); 
			}
			else{ 
				icon.getConnection().rollback (); 
			}
		} catch (SQLException e){ 
			throw new PersistenciaException(e.getMessage());
		} 
		conexiones [tope] = cone; 
		tope++; 
		notify(); 
	}

}
